/*
 * @author Stanislovas Mickus
 * @version 8
 * @date 18 August, 2013
 *
 *  Copyright (C) 2013 Stanislovas Mickus
 *
 * Licensed under the GNU General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/copyleft/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.stasmobstudios.musicplayer.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import com.stasmobstudios.musicplayer.R;
import com.stasmobstudios.musicplayer.viewgroups.StopSwipeViewPager;

public class RotaryKnobView extends ImageView {

    private float angle = 0f;
    private float theta_old = 0f;
    private int value = 100;


    float width;
    float height;

    private RotaryKnobListener listener;
    private StopSwipeViewPager ssViewPager;

    public interface RotaryKnobListener {
        public void onKnobChanged(int arg);
    }

    public void setKnobListener(RotaryKnobListener l) {
        listener = l;
    }

    private void initializeXY() {
        Rect rect = new Rect();
        getDrawingRect(rect);

        width = rect.exactCenterX();
        height = rect.exactCenterY();
    }

    public RotaryKnobView(Context context) {
        super(context);
        initializeXY();
        initialize();
    }

    public RotaryKnobView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initializeXY();
        initialize();
    }

    public RotaryKnobView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initializeXY();
        initialize();
    }

    private float getTheta(float x, float y) {
        Rect rect = new Rect();
        getDrawingRect(rect);


        float sx = x - rect.exactCenterX();
        float sy = -1 * y + rect.exactCenterY();
        float length = (float) Math.sqrt(sx * sx + sy * sy);
        float nx = (int) sx / length;
        float ny = (int) sy / length;
        float theta = (float) Math.atan2(ny, nx);
        float theta2 = (float) ((theta < 0) ? theta + 2 * Math.PI : theta);

        return theta2;

    }

    public void initialize() {
        int viewID = this.getId();
        if (viewID == R.id.volumeKnob)
            this.setImageResource(R.drawable.volume);
        else if (viewID == R.id.bassKnob)
            this.setImageResource(R.drawable.low);
        else
            this.setImageResource(R.drawable.high);

        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    v.setBackgroundResource(R.drawable.knb_light);
                    ssViewPager.setLockEnabled(true);
                }
                else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
                    v.setBackgroundResource(R.drawable.knb_apatinis);
                    ssViewPager.setLockEnabled(false);
                }

                int action = event.getAction();
                int actionCode = action & MotionEvent.ACTION_MASK;
                if (actionCode == MotionEvent.ACTION_POINTER_DOWN) {
                    float x = event.getX(0);
                    float y = event.getY(0);
                    theta_old = getTheta(x, y);
                } else if (actionCode == MotionEvent.ACTION_MOVE) {
                    invalidate();

                    float x = event.getX(0);
                    float y = event.getY(0);

                    float theta = getTheta(x, y);
                    float delta_theta = theta - theta_old;

                    theta_old = theta;

                    int direction = (delta_theta < 0) ? 1 : -1;
                    if ((value + direction >= 0) && (value + direction <= 100)) {
                        value += direction;
                        angle += 3.588 * direction;
                        notifyListener(direction);
                    }

                }
                return true;
            }

        });
    }

    private void notifyListener(int arg) {
        int viewID = this.getId();
        if (viewID == R.id.bassKnob)
            this.setImageResource(R.drawable.low);
        if (null != listener)
            listener.onKnobChanged(arg);
    }

    protected void onDraw(Canvas c) {
        c.rotate(angle, getWidth() / 2, getHeight() / 2);
        super.onDraw(c);
    }

    public void setValue(int value) {
        this.value = value;
        angle = value * 3.588f;

        invalidate();
    }

    public void setStopSwipeViewPager(StopSwipeViewPager mViewPager) {
        this.ssViewPager = mViewPager;
    }

}